package com.ykl.demo.service.impl;

import com.ykl.base.service.AbstractJpaCompService;
import com.ykl.demo.comp.SpcRoomComp;
import com.ykl.demo.comp.SpcStationComp;
import com.ykl.demo.entity.SpcRoom;
import com.ykl.demo.entity.SpcStation;
import com.ykl.demo.model.RoomImportResModel;
import com.ykl.demo.service.SpcRoomService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import java.io.*;
import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class SpcRoomServiceImpl extends AbstractJpaCompService<SpcRoom> implements SpcRoomService {

    private SpcRoomComp mmComp;

    @Autowired
    private SpcStationComp mmCompStation;

    public SpcRoomServiceImpl(SpcRoomComp comp) {
        super(comp);
        this.mmComp = comp;
    }

    @Override
    public Page<SpcRoom> querySpcRoom(String roomId, String roomName, String roomNameContains, String stationNameStart, int pgIdxB0, int pgSize, List<Sort.Order> sorts) {
        return mmComp.querySpcRoom(roomId, roomName, roomNameContains, stationNameStart,buildPageable(pgIdxB0, pgSize, sorts));
    }

    @Override
    public byte[] exportAll(Charset charset) {
        byte[] data = new byte[0];
        try (ByteArrayOutputStream out=new ByteArrayOutputStream()){
            out.write("机房ID,机房名称,所属局站名称,机房地址,经度,纬度,机房等级,机房类型,投产时间\n".getBytes(charset));
            DecimalFormat df = new DecimalFormat("0.0#####");
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
            mmComp.query4Export().forEach(c->{
                String roomId = c.getRoomId();
                String roomName = c.getChinaName();
                String roomStation = c.getStationName();
                String roomAdd = c.getAddress();
                String x = df.format(c.getX());
                String y = df.format(c.getY());
                String classId = c.getClassId();
                String typeId = c.getTypeId();
                String startDt =sdf.format(c.getStartUseDate());

                String ln = String.format("%s,%s,%s,%s,%s,%s,%s,%s,%s\n", roomId, roomName, roomStation, roomAdd, x, y, classId, typeId, startDt);
                try {
                    out.write(ln.getBytes(charset));
                } catch (IOException e) {
                    log.warn(e.getLocalizedMessage(),e);
                }
            });
            out.flush();
            data = out.toByteArray();
        }catch (IOException e){
            log.warn(e.getLocalizedMessage(),e);
        }
        return data;
    }

    @Override
    public List<RoomImportResModel> importFromCsv(String filename, byte[] bytes) {
        if(bytes==null||bytes.length==0){
            return Collections.emptyList();
        }

        List<RoomImportResModel> ls = new ArrayList<>();
        try(
            ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
            InputStreamReader isr = new InputStreamReader(bais);
            BufferedReader br = new BufferedReader(isr)
        ){
            String line;
            int rowNo = 0;
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
            while((line = br.readLine())!=null){
                rowNo++;

                if(rowNo==1){
                    //跳过标题行
                    continue;
                }

                String[] fields = line.split(",");
                if(fields==null||fields.length!=9){
                    ls.add(RoomImportResModel.ofReason(String.format("文件%s第%s行字段数量与模板格式不符", filename,rowNo)));
                    continue;
                }
                Date sud;
                try {
                    sud = sdf.parse(fields[8]);
                } catch (ParseException e) {
                    ls.add(RoomImportResModel.ofReason(String.format("文件%s第%s行投产时间字段的值'%s'与模板格式'yyyy-MM-dd hh:mm:ss'不符", filename, rowNo, fields[8])));
                    continue;
                }

                String stationName = fields[2];


                SpcStation station = mmCompStation.findByStationName(stationName)
                        .orElseGet(()->mmCompStation.createStationByName(stationName));
                //机房ID,机房名称,所属局站名称,机房地址,经度,纬度,机房等级,机房类型,投产时间
                RoomImportResModel mdl = RoomImportResModel.builder()
                        .roomId(fields[0])
                        .chinaName(fields[1])
                        .stationId(station.getStationId())
                        .stationName(stationName)
                        .address(fields[3])
                        .x(new BigDecimal(fields[4]))
                        .y(new BigDecimal(fields[5]))
                        .classId(fields[6])
                        .typeId(fields[7])
                        .startUseDate(sud)
                        .build();
                ls.add(mmComp.importRoom(filename, rowNo, station, mdl));
            }

        } catch (IOException e) {
            log.warn(e.getLocalizedMessage(),e);
        }

        return ls;
    }

    @Override
    public byte[] buildImportResultOutput(List<RoomImportResModel> results, Charset charset) {

        DecimalFormat df = new DecimalFormat("0.0#####");
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

        byte[] data = new byte[0];
        try(ByteArrayOutputStream out=new ByteArrayOutputStream()) {
            out.write("机房ID,机房名称,所属局站名称,机房地址,经度,纬度,机房等级,机房类型,投产时间,导入结果\n".getBytes(charset));
            results.forEach(c -> {
                //log.info("结果:{}", c.toLineNonReturnChar(df, sdf1));
                try {
                    out.write(c.toLineWithReturnChar(df, sdf1,"\n").getBytes(charset));
                } catch (IOException e) {
                    log.warn(e.getLocalizedMessage(),e);
                }
            });
            out.flush();
            data = out.toByteArray();
        } catch (IOException e) {
            log.warn(e.getLocalizedMessage(),e);
        }

        return data;
    }


}
